package com.changhong.framework.sdfs.namenode.server.transport;


import com.changhong.framework.sdfs.namenode.server.builder.NameNodeBuilder;
import com.changhong.framework.sdfs.namenode.server.constant.ResponseCodeType;
import com.changhong.framework.sdfs.namenode.server.datanode.DataNodeInfo;
import com.changhong.framework.sdfs.namenode.server.directory.FileManagerSystem;
import com.changhong.framework.sdfs.namenode.server.register.DataNodeRegistry;
import com.changhong.framework.sdfs.namenode.server.utils.DataNodeIdUtils;
import com.changhong.framework.sdfs.rpc.domain.*;
import com.changhong.framework.sdfs.rpc.rpcservice.NameNodeServiceGrpc;
import io.grpc.stub.StreamObserver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 接收外部的RPC调用来处理相应的请求和相应
 * @author Summer
 */
public class NameNodeRpcServiceImpl implements NameNodeServiceGrpc.NameNodeService{

    private static final Logger logger = LoggerFactory.getLogger(NameNodeRpcServiceImpl.class);
    /**
     * 负责管理元数据的核心组件：管理的是一些文件目录树，支持权限设置
     */
    private final FileManagerSystem fileManagerSystem;
    /**
     * 负责管理集群中所有的Datanode的组件
     */
    private final DataNodeRegistry dataNodeRegistry;

    public NameNodeRpcServiceImpl(){
        this.fileManagerSystem = NameNodeBuilder.getInstance(FileManagerSystem.class);
        this.dataNodeRegistry = NameNodeBuilder.getInstance(DataNodeRegistry.class);
    }

    @Override
    public void register(RegisterRequest request, StreamObserver<RegisterResponse> responseObserver) {
        try {
            dataNodeRegistry.register(getDataNodeInfoByRegisterRequest(request));
            responseObserver.onNext(RegisterResponse.newBuilder().setStatus(ResponseCodeType.SUCCESS).build());
            responseObserver.onCompleted();
        }catch (Exception e){
            logger.error("注册出现问题");
        }

    }

    private DataNodeInfo getDataNodeInfoByRegisterRequest(RegisterRequest request){
        DataNodeInfo dataNodeInfo=new DataNodeInfo();
        dataNodeInfo.setInstanceId(request.getInstanceId());
        dataNodeInfo.setAppGroupName(request.getAppGroupName());
        dataNodeInfo.setAppName(request.getAppName());
        dataNodeInfo.setHostName(request.getHostName());
        dataNodeInfo.setMetadata(request.getMetadataMap());
        dataNodeInfo.setPort(request.getPort());

        return dataNodeInfo;
    }

    private DataNodeInfo getDataNodeInfoByHeartbeatRequest(HeartbeatRequest request){
        DataNodeInfo dataNodeInfo=new DataNodeInfo();
        dataNodeInfo.setInstanceId(request.getInstanceId());
        dataNodeInfo.setAppGroupName(request.getAppGroupName());
        dataNodeInfo.setAppName(request.getAppName());
        dataNodeInfo.setHostName(request.getHostName());
        dataNodeInfo.setMetadata(request.getMetadataMap());
        dataNodeInfo.setPort(request.getPort());
        return dataNodeInfo;
    }

    @Override
    public void heartbeat(HeartbeatRequest request, StreamObserver<HeartbeatResponse> responseObserver) {
        try {
            dataNodeRegistry.renew(request.getAppName(), DataNodeIdUtils.generalDataNodeId(getDataNodeInfoByHeartbeatRequest(request)));
            responseObserver.onNext(HeartbeatResponse.newBuilder().setStatus(ResponseCodeType.SUCCESS).build());
        }catch (Exception e){
            e.getStackTrace();
            logger.error("心跳出现问题",e);
        }
    }

    @Override
    public void createDir(DirectoryRequest request, StreamObserver<DirectoryResponse> responseObserver) {
        try {
            fileManagerSystem.createDir(request.getPath());
            responseObserver.onNext(DirectoryResponse.newBuilder().setMessage("成功创建文件目录").setStatus(ResponseCodeType.SUCCESS).build());
            responseObserver.onCompleted();
        }catch (Exception e){
            e.getStackTrace();
            logger.error("创建文件目录报错",e);
        }

    }

    @Override
    public void deleteDir(DirectoryRequest request, StreamObserver<DirectoryResponse> responseObserver) {

    }

    @Override
    public void modifyDir(DirectoryRequest request, StreamObserver<DirectoryResponse> responseObserver) {

    }

    @Override
    public void moveDir(DirectoryRequest request, StreamObserver<DirectoryResponse> responseObserver) {

    }

    @Override
    public void uploadFile(FileRequest request, StreamObserver<FileResponse> responseObserver) {

    }

    @Override
    public void deleteFile(FileRequest request, StreamObserver<FileResponse> responseObserver) {

    }

    @Override
    public void moveFile(FileRequest request, StreamObserver<FileResponse> responseObserver) {

    }

    @Override
    public void scanFile(FileRequest request, StreamObserver<FileResponse> responseObserver) {

    }

}
